package com.ruoyi.production.service.impl;

import com.ruoyi.base.util.GenCodeUtils;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.production.domain.PlanModelInfo;
import com.ruoyi.production.domain.WorkOrderInfo;
import com.ruoyi.production.mapper.WorkOrderInfoMapper;
import com.ruoyi.production.service.IWorkOrderInfoService;
import com.ruoyi.project.domain.ProjectModelInfo;
import com.ruoyi.project.mapper.ProjectModelInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 工单Service业务层处理
 *
 * @author ruoyi
 * @date 2022-09-01
 */
@Service
public class WorkOrderInfoServiceImpl implements IWorkOrderInfoService {
    @Autowired
    private WorkOrderInfoMapper workOrderInfoMapper;
    @Autowired
    private ProjectModelInfoMapper projectModelInfoMapper;

    /**
     * 查询工单
     *
     * @param id 工单主键
     * @return 工单
     */
    @Override
    public WorkOrderInfo selectWorkOrderInfoById(Long id) {
        //构件总数量：250     构件总重量：377t
        WorkOrderInfo workOrderInfo = workOrderInfoMapper.selectWorkOrderInfoById(id);
        Long componentsTotalNumber = 0L;
        Double componentsTotalWeight = 0d;
        for (PlanModelInfo planModelInfo : workOrderInfo.getPlanModelInfoList()) {
            componentsTotalNumber += planModelInfo.getCount();
            componentsTotalWeight += planModelInfo.getGrossWeight() * planModelInfo.getCount();
        }
        workOrderInfo.setComponentsTotalNumber(componentsTotalNumber);
        workOrderInfo.setComponentsTotalWeight(componentsTotalWeight);
        return workOrderInfoMapper.selectWorkOrderInfoById(id);
    }

    /**
     * 查询工单列表
     *
     * @param workOrderInfo 工单
     * @return 工单
     */
    @Override
    public List<WorkOrderInfo> selectWorkOrderInfoList(WorkOrderInfo workOrderInfo) {
        return workOrderInfoMapper.selectWorkOrderInfoList(workOrderInfo);
    }

    /**
     * 新增工单
     *
     * @param workOrderInfo 工单
     * @return 结果
     */
    @Transactional(rollbackFor = {Exception.class, ServiceException.class})
    @Override
    public int insertWorkOrderInfo(WorkOrderInfo workOrderInfo) {
        workOrderInfo.setCreateTime(DateUtils.getNowDate());
        SysUser user = SecurityUtils.getLoginUser().getUser();
        workOrderInfo.setCreateBy(user.getUserName());
        workOrderInfo.setWorkOrderNo(GenCodeUtils.getWorkOrderInfoNo());
        int rows = workOrderInfoMapper.insertWorkOrderInfo(workOrderInfo);
        insertPlanModelInfo(workOrderInfo);
        return rows;
    }

    /**
     * 修改工单
     *
     * @param workOrderInfo 工单
     * @return 结果
     */
    @Transactional(rollbackFor = {Exception.class, ServiceException.class})
    @Override
    public int updateWorkOrderInfo(WorkOrderInfo workOrderInfo) {
        workOrderInfo.setUpdateTime(DateUtils.getNowDate());
        //获取工单下全部计划
        List<PlanModelInfo> planModelInfoList = workOrderInfoMapper.getPlanModelInfoList(workOrderInfo.getId());
        Map<Long, PlanModelInfo> collect = new HashMap<>();
        if (!planModelInfoList.isEmpty()){
            collect = planModelInfoList.stream().collect(Collectors.toMap(PlanModelInfo::getId, Function.identity(), (k1, k2) -> k2));
        }
        for (PlanModelInfo planModelInfo : workOrderInfo.getPlanModelInfoList()) {
            editPlanModelInfo(planModelInfo);
            if (collect.containsKey(planModelInfo.getId())){
                collect.remove(planModelInfo.getId());
            }
        }
        if (!collect.isEmpty()){
            for (Long aLong : collect.keySet()) {
                delPlanModelInfo(aLong);
            }
        }
        return workOrderInfoMapper.updateWorkOrderInfo(workOrderInfo);
    }

    /**
     * 批量删除工单
     *
     * @param ids 需要删除的工单主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteWorkOrderInfoByIds(Long[] ids) {
        for (Long id : ids) {
            delPlanModelInfo(id);
        }
        return workOrderInfoMapper.deleteWorkOrderInfoByIds(ids);
    }

    /**
     * 删除工单信息
     *
     * @param id 工单主键
     * @return 结果
     */
    @Transactional(rollbackFor = {Exception.class,})
    @Override
    public int deleteWorkOrderInfoById(Long id) {
        delPlanModelInfo(id);
        return workOrderInfoMapper.deleteWorkOrderInfoById(id);
    }


    /**
     * 获取构件表格
     *
     * @param planModelInfo
     * @return
     */
    @Override
    public List<PlanModelInfo> getPlanModelInfo(PlanModelInfo planModelInfo) {
        return workOrderInfoMapper.getCompomentList(planModelInfo);
    }

    /**
     * 新增生产计划信息
     *
     * @param workOrderInfo 工单对象
     */
    public void insertPlanModelInfo(WorkOrderInfo workOrderInfo) {
        //获取项目下构件
        List<PlanModelInfo> planModelInfoList = workOrderInfo.getPlanModelInfoList();
        Long id = workOrderInfo.getId();
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (StringUtils.isNotNull(planModelInfoList)) {
            List<PlanModelInfo> list = new ArrayList<PlanModelInfo>();
            for (PlanModelInfo planModelInfo : planModelInfoList) {
                savePlanModelInfo(planModelInfo);
                planModelInfo.setWorkOrderId(id);
                planModelInfo.setCreateBy(user.getUserName());
                list.add(planModelInfo);
                savePlanModelInfo(planModelInfo);
            }
            if (list.size() > 0) {
                workOrderInfoMapper.batchPlanModelInfo(list);
            }
        }
    }

    @Override
    public List<PlanModelInfo> getCompomentList(PlanModelInfo planModelInfo) {
        return workOrderInfoMapper.getCompomentList(planModelInfo);
    }


    /**
     * 检查构件剩余量，不足时添加失败
     *
     * @param planModelInfo
     */
    private void savePlanModelInfo(PlanModelInfo planModelInfo) {
        ProjectModelInfo projectModelInfo = projectModelInfoMapper.selectProjectModelInfoById(planModelInfo.getModelId());
        if (planModelInfo.getCount() > projectModelInfo.getYieldCount()) {
            throw new ServiceException("工单创建失败，项目中构件剩余可生产量不足！");
        }
        projectModelInfo.setYieldCount(projectModelInfo.getYieldCount() - planModelInfo.getCount());
        if (projectModelInfo.getYieldCount() < 0) {
            throw new ServiceException("工单创建失败，项目中构件剩余可生产量不足！");
        }
        projectModelInfoMapper.updateProjectModelInfo(projectModelInfo);
    }

    /**
     * 删除一个构件还原剩余量
     *
     * @param id
     */
    private void delPlanModelInfo(Long id) {
        PlanModelInfo planModelInfo = workOrderInfoMapper.getPlanModelInfo(id);
        ProjectModelInfo projectModelInfo = projectModelInfoMapper.selectProjectModelInfoById(planModelInfo.getModelId());
        projectModelInfo.setYieldCount(projectModelInfo.getYieldCount() + planModelInfo.getCount());
        workOrderInfoMapper.delPlanModelInfo(planModelInfo.getId());
        projectModelInfoMapper.updateProjectModelInfo(projectModelInfo);
    }

    /**
     * 修改构件
     *
     * @param oldPlanModelInfo
     */
    public void editPlanModelInfo(PlanModelInfo oldPlanModelInfo) {
        PlanModelInfo planModelInfo = workOrderInfoMapper.getPlanModelInfo(oldPlanModelInfo.getId());
        //先还原，再减
        ProjectModelInfo projectModelInfo = projectModelInfoMapper.selectProjectModelInfoById(planModelInfo.getModelId());
        projectModelInfo.setYieldCount(projectModelInfo.getYieldCount() + planModelInfo.getCount());
        if (oldPlanModelInfo.getCount() > projectModelInfo.getYieldCount()) {
            throw new ServiceException("工单创建失败，项目中构件剩余可生产量不足！");
        }
        projectModelInfo.setYieldCount(projectModelInfo.getYieldCount() - oldPlanModelInfo.getCount());
        if (projectModelInfo.getYieldCount() < 0) {
            throw new ServiceException("工单创建失败，项目中构件剩余可生产量不足！");
        }
        workOrderInfoMapper.updatePlanModelInfo(oldPlanModelInfo);
        projectModelInfoMapper.updateProjectModelInfo(projectModelInfo);
    }
}
